#pragma once
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <memory.h>
#include <string>
#include <list>
#include <mutex>
#include <thread>
#include <vector>
#include <map>
#include <functional>

struct DataPacket{
  const uint8_t* data;
  uint32_t len;
  int src;
  int dst;
};

class TcpSerVer
{
private:
    /* data */
    std::string m_ip_;
    int32_t m_port_;

    int m_server_fd_;
    int m_client_fd_;
    struct sockaddr_in m_server_sockaddr_;

    std::list<DataPacket> send_data_buf_;
    std::mutex tx_buf_mutex_;
    // int m_event_socket_;

    bool m_start_process_flag_;
    std::shared_ptr<std::thread> process_thread_;
    std::shared_ptr<std::thread> send_thread_;


    std::map<int,sockaddr_in> m_client_vec_;
    std::vector<int> m_delete_vec_;

    std::function<void(void* param,DataPacket& data)> m_rx_callback_;
    void* m_rx_callback_param_;

    void Listen();

    bool ProcessLoop();
public:
    TcpSerVer(/* args */);

    ~TcpSerVer();

    bool Init(std::string ip, int32_t port);

    bool Start();

    bool Stop();

    bool SendData(const uint8_t *data, int32_t len, int fd);

    void RegCallback( std::function<void(void* param, DataPacket& data)> call, void* param){
        m_rx_callback_ = call;
        m_rx_callback_param_ = param;
    };

    std::map<int,sockaddr_in>& getClients(){
        return m_client_vec_;
    }

    
};
